/*
* Matthew Parker
* CPE 301
* Assignment 1
* 2/19/2014
*
* Designed for the ATmega328P and made in AtmelStudio 6.1
* 
* This program will...
* 1. Generate 20 numbers between (30, 250) and store them on the stack
     The numbers must not be in ascending or decending order
* 2. Check if each number is divisible by 3 or 5
*    All numbers divisible by 3 are summed and placed in register 20:21
*    All numbers divisible by 5 are summed and placed in register 23:24
*/

.INCLUDE "M328Pdef.inc"
.MACRO  INITSTACK
		LDI  R16,HIGH(RAMEND)
		OUT  SPH,R16 
		LDI  R16,LOW(RAMEND)
		OUT  SPL,R16
.ENDMACRO
		INITSTACK

		;//The below code generates the 20 numbers used
		;// {31, 57, 50, 76, 69, 95, 88, 114, 107, 133, 126, 152, 145, 171, 164, 190, 183, 209, 202, 228}
		LDI R16, 38 ;//the starting amount
		LDI R17, 7	;//amount to subtract on odd numbered steps
		LDI R18, 26 ;//amount to add on even numbered steps
		LDI R19, 10  ;//counts the number of loops (NumbersGenerated/2). 1 loop = 1 odd step + 1 even step.
GenerateNumbers:
		sub R16, R17
		push R16
		add R16, R18
		push R16
		subi R19, 1
		BRNE GenerateNumbers

		;//The below code is used to check if each number is divisible by 3 or 5
		;//First, it reduces the number to less than or equal to 15 without changing its divisibility with 3 or 5
		;//Then, it checks if the reduced number is divisible by 3 or 5 seperately
		LDI R19, 20 ;//Loop counter for checking each of the 20 numbers
SelectNewNumber:
		pop R16		;//The original number, not to be changed
		MOV R17, R16;//Temp_Number that will be changed to check for divisible by 3 or 5
ReduceNumber:
		;// Subtract 15 (or a multiple of 15 if the number is large) until Temp_Number is less than 15
		MOV R18, R17 ;//copy of Temp_Number for branch tests
		subi R18, 15
		;//BRPL is not working
		BRSH GreaterThanFifteen
		RJMP DivThree
	GreaterThanFifteen:
		subi R18, 15
		BRSH GreaterThanThirty
		subi R17, 15
		RJMP ReduceNumber
	GreaterThanThirty:
		subi R18, 60
		BRSH GreaterThanNinety
		subi R17, 30
		RJMP ReduceNumber
	GreaterThanNinety:
		subi R17, 90
		RJMP ReduceNumber


DivThree:
	;//check if divisible by 3
	;// Subtract 3 until Temp_Number is less than or equal to 0
	;//it is divisible by 3 only if it becomes 0
		MOV R18, R17
		;LDI R19, 3
		;add R18, R19 ;//Add 3 just in case Temp_Number was 0
		subi R18, -3
	DivThreeLoop:
		subi R18, 3
		BRMI DivFive ;//Not divisible by 3
		subi R18, 0 ;//Check if not zero
		BRNE DivThreeLoop

;//At this point, the number must have been divisible by 3
SumDivThree:
	;//Add the original number to a cummulative sum of numbers divisible by 3
	add R21, R16
	BRCC DivFive
	;//8-bit carry:
	inc R20
		
DivFive:
	;//check if divisible by 5
	;// Subtract 5 until Temp_Number is less than or equal to 0
	;//it is divisible by 5 only if it becomes 0
		MOV R18, R17
		;LDI R19, 5
		;add R18, R19 ;//Add 5 just in case Temp_Number was 0
		subi R18, -5
	DivFiveLoop:
		subi R18, 5
		BRMI NextNumber ;//Not divisible by 5
		subi R18, 0 ;//Check if not zero
		BRNE DivFiveLoop

;//At this point, the number must have been divisible by 5
SumDivFive:
	;//Add the original number to a cummulative sum of numbers divisible by 5
	add R24, R16
	BRCC NextNumber
	;//8-bit carry:
	inc R23

NextNumber:
	;//Update the counter and loop if not done
	subi R19, 1
	BRNE SelectNewNumber

DONE:
	